package edu.del.newsreleasesystem.comfirm;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 * 封装消息并发送到 RabbitMQ，同时支持携带回调业务标识，用于失败处理
 */
@Component
@RequiredArgsConstructor
public class RabbitManager<T> {

    private final RabbitTemplate rabbitTemplate;
    private final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 发送消息，并指定用于处理失败回调的 ConfirmCallbackService bean 名称
     *
     * @param exchange         交换机名称
     * @param routingKey       路由键
     * @param callbackBeanName 处理投递失败回调的 ConfirmCallbackService 实现类 Bean 名称，比如 "newsServiceImpl"
     * @param data             业务消息对象，比如 NewsSyncMessage
     */
    public void send(String exchange, String routingKey,
                     String callbackBeanName, T data) {
        try {
            // 生成唯一 ID
            String id = UUID.randomUUID().toString();

            // 构建自定义 CorrelationData，携带 callbackBeanName 和原始消息
            MyCorrelationData cdata = new MyCorrelationData(id, callbackBeanName, data);

            // 序列化业务数据为字节数组
            byte[] bytes = objectMapper.writeValueAsBytes(data);
            Message message = new Message(bytes);

            // 发送消息，并绑定 CorrelationData（用于 ConfirmCallback）
            rabbitTemplate.convertAndSend(exchange, routingKey, data, cdata);

        } catch (Exception e) {
            throw new RuntimeException("发送 RabbitMQ 消息失败", e);
        }
    }
}